#!/bin/bash

export VERSION=0.1.0

echo "Configure for matvec version $VERSION"
echo "Configuring matvec:"

###
# Functions here...
# 

_die_clean(){
    rm -f config.mak
    rm -f config.h
    rm -f tmp.c
    exit $1
}

bits64(){
    case $1 in
	x86_64|ia64) return 0 ;;
	*) return 1 ;;
    esac
}

bits32(){
    case $1 in
	i386) return 0 ;;
	*) return 1 ;;
    esac
}

###
# First make the config.mak file.
#

if [ -e config.mak ]; then
    rm config.mak
fi
touch config.mak

###
# Set the version string here
#
echo "VERSION=$VERSION" >> config.mak

# Set the architecture
_arch=`uname -p 2>&1`
case $_arch in 
    x86_64)
        arch=-mtune=k8
        proc=x86_64
        ;;
    ia64)
	arch=-mtune=k8
	proc=ia64
	;;
    sparc)
        arch=-mtune=ultrasparc
        proc=sparc
        ;;
    i[3-9]86|ia32)
        arch=-mtune=i386
        proc=i386
        ;;
    *)
        arch=-mtune=generic
        proc=generic
        ;;
esac

echo "Compiling for architecture: $proc"

# check for *NIX, right now its not likely to run on anything else.
echo -n "Checking for *NIX system: "
system=`uname -s 2>&1`

case $system in
    Linux|Solaris|SunOS) 
        echo "Yes."
        ;;
    *)
        echo "no."
        echo "You do not appear to have linux. You need linux for the moment."
        _die_clean 1
        ;;
esac

# check for gcc.
echo -n "Checking for gcc: "
GCC=`which gcc 2>&1`

if [ -x $GCC ]; then
    echo "CC=gcc" >> config.mak
    echo "yes.";
else
    echo "no."
    echo "gcc does not appear to be on your system. You need to have gcc."
    echo "Get gcc, then try again."
    _die_clean 1
fi

# check our gcc opts
echo -n "Checking if gcc works: "
C_FLAGS="-fPIC -Wall -c -g -O3 $arch"
C_TEST_FLAGS="-g -O3 $arch";

# make a temp c file to do the tests on
cat >tmp.c <<EOF
int main(int argc, char **argv){
  return 0;
}
EOF

$GCC tmp.c -o tmp
gcc_res=$?
./tmp
tmp_res=$?

if [ "$gcc_res" != "0" ]; then
    echo "PANIC: gcc does not appear to work."
    _die_clean 1
elif [ "$tmp_res" != "0" ]; then
    echo "PANIC: gcc does not appear to work."
    _die_clean 1
else
    rm tmp
fi

$GCC $C_FLAGS -o tmp tmp.c

if [ "$?" != "0" ]; then
    echo "PANIC: gcc does not appear to work."
    _die_clean 1
else
    rm tmp
fi

rm -f tmp.c

echo "yes."

# Set the LD flags here.
case $system in
    SunOS) 
        LD_FLAGS="-G -h libmatvec.so";
        #C_TEST_FLAGS="-R . $C_TEST_FLAGS"
        ;;
    *)
        LD_FLAGS="-shared -soname libmatvec.so"
        ;;
esac

# look for nasm or yasm
have_nasm=
have_yasm=

echo -n "Checking for nasm: "
nasm=`which nasm 2>&1`
if [ -x "$nasm" ]; then
    have_nasm=1
    echo "yes."
else
    echo "no."
fi

echo -n "Checking for yasm: "
yasm=`which yasm 2>&1`
if [ -x "$yasm" ]; then
    have_yasm=1
    echo "yes."
else
    echo "no."
fi

## If we are 64 bit then try and use yasm
## If we are 32 bit try and use nasm instead

_asm=

if bits32 $proc ; then
    if [ $have_nasm ]; then
	_asm=nasm
    elif [ $have_yasm ]; then
	# Fall back on to yasm
	_asm=yasm
    else
	echo "Error: You need yasm or nasm to compile this"
	_die_clean 1
    fi
fi

if bits64 $proc ; then
    if [ $have_yasm ]; then
	_asm=yasm
    elif [ $have_nasm ]; then
	# Fall back to nasm
	_asm=nasm
    else
	echo "Error: You need yasm or nasm to compile this"
	_die_clean 1
    fi
fi

_asm_flags=

if bits64 $proc && [ $have_yasm ]; then
    #_libs=libmatvec_asm.so
    _asm_flags="-f elf64"
else
    _asm_flags="-f elf"
fi

echo "ASM=$_asm" >> config.mak
echo "ASM_FLAGS=$_asm_flags" >> config.mak
echo "LIBS=$_libs" >> config.mak
echo "LD_FLAGS=$LD_FLAGS" >> config.mak
echo "C_FLAGS=$C_FLAGS" >> config.mak
echo "C_TEST_FLAGS=$C_TEST_FLAGS" >> config.mak

echo "Generating config.mak: OK"
echo -n "Generating config.h: "

if [ -e config.h ]; then
    rm -f config.h
fi

# Set all of the defines here

if [ "$proc" = "x86_64" ]; then
    x86_64="#  define _VM_PROC_x86_64"
else
    x86_64="#  undef _VM_PROC_x86_64"
fi

cat >config.h <<EOF
#ifndef _CONFIG_H
#  define _CONFIG_H
#  define _VM_VERSION       "$VERSION"
#  define _VM_ARCH          "$proc"
$x86_64
#endif
EOF

echo "OK"

echo -n "Generating arch.s: "

if [ -e arch.s ]; then
    rm -f arch.s
fi

bp=
sp=

if bits64 $proc && [ $have_yasm ]; then
    bp=rbp
    sp=rsp
    ws=8
else
    bp=ebp
    sp=esp
    ws=4
fi

cat >arch.s <<EOF
%ifndef _ARCH_S
%define _ARCH_S

%define WSIZE $ws

%macro preamble 0
        push $bp
        mov  $bp, $sp
%endmacro

%macro postamble 0
        pop  $bp
        ret
%endmacro

%endif
EOF

echo "OK"